package com.developer.platform.domain.service.impl;

import com.developer.platform.domain.User;
import com.developer.platform.domain.repository.IUserRepository;
import com.developer.platform.domain.security.AuthenticationInfo;
import com.developer.platform.domain.security.UserDetails;
import com.developer.platform.domain.service.ILoginService;
import com.developer.platform.infrastructure.client.ApiClient;
import com.developer.platform.infrastructure.client.ApiClient.ApiUser;
import com.developer.platform.infrastructure.enums.LoginType;
import com.developer.platform.infrastructure.enums.StatusEnum;
import com.developer.platform.infrastructure.error.LoginErrorType;
import com.veeker.core.exceptions.BusinessException;
import java.util.Objects;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

/**
 * @author ：qiaoliang
 * @date ：2020-11-09
 */
@Service
public class AccountLoginHandle implements ILoginService {

    private final ApiClient apiClient;
    private final IUserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

    public AccountLoginHandle(
        ApiClient apiClient,
        IUserRepository userRepository,
        PasswordEncoder passwordEncoder) {
        this.apiClient = apiClient;
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public Authentication login(Object principal, Object credentials) {
        User user = userRepository.findByUsername((String)principal);
        //  校验账户
        //BusinessException.isNull(user, ACCOUNT_IS_NULL_ERROR);
        if(Objects.isNull(user)){
            return this.apiLogin(principal, credentials);
        }
        //  校验状态
        BusinessException.isTrue(
            StatusEnum.N.equals(user.getStatus()), LoginErrorType.ACCOUNT_IS_STATUS_ERROR);

        //  校验用户密码
        BusinessException.isFalse(passwordEncoder.matches(credentials.toString(),
                user.getPassword()), LoginErrorType.PASSWORD_ERROR);

        return new AuthenticationInfo(new UserDetails(user.getId(), user.getName(), user.getAvatar()));
    }

    private Authentication apiLogin(Object principal, Object credentials){
        ApiUser login = apiClient.login(principal, credentials);
        User user = new User(principal.toString(), passwordEncoder.encode(credentials.toString()), login.getNickName(),
            login.getAvatar(), login.getSchool());
        userRepository.save(user);
        return new AuthenticationInfo(new UserDetails(user.getId(), user.getName(), user.getAvatar()));
    }

    @Override
    public LoginType only() {
        return LoginType.ACCOUNT;
    }

}
